package models

import (
	"time"

	"github.com/google/uuid"
	"gorm.io/gorm"
)

// User represents a platform user
type User struct {
	ID        uuid.UUID      `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	Username  string         `json:"username" gorm:"uniqueIndex;not null"`
	Email     string         `json:"email" gorm:"uniqueIndex;not null"`
	Password  string         `json:"-" gorm:"not null"` // Hidden in JSON response
	FirstName string         `json:"first_name"`
	LastName  string         `json:"last_name"`
	Avatar    string         `json:"avatar"`
	Status    UserStatus     `json:"status" gorm:"default:active"`
	Roles     []Role         `json:"roles" gorm:"many2many:user_roles;"`
	CreatedAt time.Time      `json:"created_at"`
	UpdatedAt time.Time      `json:"updated_at"`
	DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}

type UserStatus string

const (
	UserStatusActive    UserStatus = "active"
	UserStatusInactive  UserStatus = "inactive"
	UserStatusSuspended UserStatus = "suspended"
)

// Role represents a user role for RBAC
type Role struct {
	ID          uuid.UUID    `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	Name        string       `json:"name" gorm:"uniqueIndex;not null"`
	Description string       `json:"description"`
	Permissions []Permission `json:"permissions" gorm:"many2many:role_permissions;"`
	CreatedAt   time.Time    `json:"created_at"`
	UpdatedAt   time.Time    `json:"updated_at"`
}

// Permission represents a system permission
type Permission struct {
	ID          uuid.UUID `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	Name        string    `json:"name" gorm:"uniqueIndex;not null"`
	Resource    string    `json:"resource" gorm:"not null"` // e.g., "devices", "users", "telemetry"
	Action      string    `json:"action" gorm:"not null"`   // e.g., "read", "write", "delete"
	Description string    `json:"description"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
}

// UserSession represents an active user session
type UserSession struct {
	ID        uuid.UUID `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	UserID    uuid.UUID `json:"user_id" gorm:"type:uuid;not null"`
	User      User      `json:"user" gorm:"foreignKey:UserID"`
	Token     string    `json:"-" gorm:"not null;uniqueIndex"`
	UserAgent string    `json:"user_agent"`
	IPAddress string    `json:"ip_address"`
	ExpiresAt time.Time `json:"expires_at"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

// Organization represents a tenant/organization
type Organization struct {
	ID          uuid.UUID      `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	Name        string         `json:"name" gorm:"not null"`
	Slug        string         `json:"slug" gorm:"uniqueIndex;not null"`
	Description string         `json:"description"`
	Status      string         `json:"status" gorm:"default:active"`
	Settings    OrgSettings    `json:"settings" gorm:"type:jsonb"`
	CreatedAt   time.Time      `json:"created_at"`
	UpdatedAt   time.Time      `json:"updated_at"`
	DeletedAt   gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}

type OrgSettings struct {
	MaxDevices     int                    `json:"max_devices"`
	MaxUsers       int                    `json:"max_users"`
	RetentionDays  int                    `json:"retention_days"`
	Features       []string               `json:"features"`
	CustomSettings map[string]interface{} `json:"custom_settings"`
}

// UserOrganization represents the relationship between users and organizations
type UserOrganization struct {
	ID             uuid.UUID    `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	UserID         uuid.UUID    `json:"user_id" gorm:"type:uuid;not null"`
	OrganizationID uuid.UUID    `json:"organization_id" gorm:"type:uuid;not null"`
	User           User         `json:"user" gorm:"foreignKey:UserID"`
	Organization   Organization `json:"organization" gorm:"foreignKey:OrganizationID"`
	Role           string       `json:"role" gorm:"not null"` // "admin", "member", "viewer"
	JoinedAt       time.Time    `json:"joined_at"`

	// Unique constraint on user-organization pair
	_ struct{} `gorm:"uniqueIndex:idx_user_org,unique"`
}
